#include "dialoglasertest.h"
#include "ui_dialoglasertest.h"
#include "log/log.h"
#include "rtc5/rtc5agent.h"
#include "../app/system/systemmonitor.h"
#include <QMessageBox>
#include <QButtonGroup>
#include <QFileDialog>

DialogLaserTest::DialogLaserTest(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogLaserTest),
    countDownTimer_(new QTimer(this))
{
    ui->setupUi(this);
    initParas();

    QButtonGroup *buttonGroup = new QButtonGroup(this);
    buttonGroup->addButton(ui->radioButton_lensTest);
    buttonGroup->addButton(ui->radioButton_calibrationTest);
    buttonGroup->addButton(ui->radioButton_gotoTest);
    buttonGroup->addButton(ui->radioButton_OntimeLighting);
    buttonGroup->addButton(ui->radioButton_Line);
    buttonGroup->addButton(ui->radioButton_circle);
    buttonGroup->addButton(ui->radioButton_Rectangle);
    buttonGroup->addButton(ui->radioButton_slice);
    ui->radioButton_lensTest->setChecked(true);
    connect(countDownTimer_, SIGNAL(timeout()), this, SLOT(on_countDownTime()));
}

DialogLaserTest::~DialogLaserTest()
{
    delete ui;
}

void DialogLaserTest::initParas()
{
    QObjectList objectList = ui->widget_savePara->children();

    for(auto it : objectList){
        if(it->metaObject()->className()==QString("QSpinBox")){
            auto value = SYSTEMCONFIG.getLongValue(PARAMETER,it->objectName().toStdString());
            dynamic_cast<QSpinBox*>(it)->setValue(value);
        }else if(it->metaObject()->className()==QString("QDoubleSpinBox")){
            auto value = SYSTEMCONFIG.getDoubleValue(PARAMETER,it->objectName().toStdString());
            dynamic_cast<QDoubleSpinBox*>(it)->setValue(value);
        }else if(it->metaObject()->className()==QString("QLineEdit")){
            auto value = SYSTEMCONFIG.getValue(PARAMETER,it->objectName().toStdString());
            dynamic_cast<QLineEdit*>(it)->setText(QString::fromStdString(value));
        }
    }
}

void DialogLaserTest::timeCountdown(int time)
{
    countDownTime = time;
    countDownTimer_->start(1000);
}

void DialogLaserTest::on_countDownTime()
{
    countDownTime -= 1;
    QString s = QString::number(countDownTime);
    ui->label_LightOutputTimeCountdown->setText(s.append("s"));
    if(0==countDownTime){
        countDownTimer_->stop();
    }
}

void DialogLaserTest::on_radioButton_laserEnable_clicked(bool checked)
{
    if (checked){
        int ret = QMessageBox::question(this, tr("Warning"),
                                        tr("Please ensure that the laser is enabled safely"),
                                        QMessageBox::No | QMessageBox::Yes);
        if(ret==QMessageBox::Yes)
        {
            if(safeCheck){
                if(SYSTEMMONITOR.laserSafeCheck()){
                    ui->radioButton_redLightEnable->setChecked(false);
                    RTC5AGENT.ctlSetLaserPinOut(0);
                    RTC5AGENT.ctlEnableLaser(true);
                }else{
                    QMessageBox::warning(this, tr("Error"),
                                         tr("Laser safe check fail , please ensure that the laser is enabled safely"),
                                         QMessageBox::Yes);
                    ui->radioButton_laserEnable->setChecked(false);
                }

            }else{
                ui->radioButton_redLightEnable->setChecked(false);
                RTC5AGENT.ctlSetLaserPinOut(0);
                RTC5AGENT.ctlEnableLaser(true);
            }
        }else{
            ui->radioButton_laserEnable->setChecked(false);
        }
    }else{
        RTC5AGENT.ctlEnableLaser(false);
    }
}

void DialogLaserTest::on_radioButton_redLightEnable_clicked(bool checked)
{
    if (checked){
        if(ui->radioButton_laserEnable->isChecked()){
            RTC5AGENT.ctlSetLaserPinOut(0);
            ui->radioButton_redLightEnable->setChecked(false);
        }else{
            RTC5AGENT.ctlSetLaserPinOut(1);
        }
    }else{
        RTC5AGENT.ctlSetLaserPinOut(0);
    }
}

void DialogLaserTest::on_radioButton_lensTest_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_LENS;
}

void DialogLaserTest::on_radioButton_calibrationTest_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_CALIBRATION;
}

void DialogLaserTest::on_radioButton_gotoTest_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_GOTO;
}

void DialogLaserTest::on_radioButton_OntimeLighting_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_ONTIME;
}

void DialogLaserTest::on_radioButton_Line_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_LINE;
}

void DialogLaserTest::on_radioButton_circle_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_CIRCLE;
}

void DialogLaserTest::on_radioButton_Rectangle_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_RECTANGLE;
}

void DialogLaserTest::on_radioButton_slice_clicked(bool checked)
{
    if(checked)
        rtc5TestType = RTC5TESTTYPE_SLICE;
}

void DialogLaserTest::on_pushButton_startTest_clicked()
{
    QMap<QString,double> paraList;
    QObjectList objectList = ui->widget_savePara->children();

    for(auto it : objectList){
        if(it->metaObject()->className()==QString("QSpinBox")){
            paraList[dynamic_cast<QSpinBox*>(it)->objectName()] = dynamic_cast<QSpinBox*>(it)->value();
        }else if(it->metaObject()->className()==QString("QDoubleSpinBox")){
            paraList[dynamic_cast<QDoubleSpinBox*>(it)->objectName()] = dynamic_cast<QDoubleSpinBox*>(it)->value();
        }
    }
    switch (rtc5TestType) {
    case RTC5TESTTYPE_LENS : {
        RTC5AGENT.testLensPara(paraList);
    } break;
    case RTC5TESTTYPE_CALIBRATION : {
        paraList["spinBox_rows"] = ui->spinBox_rows->value();
        paraList["spinBox_rowsInt"] = ui->spinBox_rowsInt->value();
        paraList["spinBox_cols"] = ui->spinBox_cols->value();
        paraList["spinBox_colsInt"] = ui->spinBox_colsInt->value();
        paraList["doubleSpinBox_R"] = ui->doubleSpinBox_R->value();
        RTC5AGENT.testCalibrationPara(paraList);
    } break;
    case RTC5TESTTYPE_GOTO : {
        paraList["laserXpos"] = ui->laserXpos->value();
        paraList["laserYpos"] = ui->laserYpos->value();
        RTC5AGENT.testGoto(paraList);
    } break;
    case RTC5TESTTYPE_ONTIME : {
        paraList["laserLightOutputTime"] = ui->laserLightOutputTime->value()*100000;
        RTC5AGENT.testTimedlight(paraList);
        timeCountdown(ui->laserLightOutputTime->value());
    } break;
    case RTC5TESTTYPE_LINE : {
        paraList["laserLineTestAX"]=(ui->laserLineTestAX->value());
        paraList["laserLineTestAY"]=(ui->laserLineTestAY->value());
        paraList["laserLineTestBX"]=(ui->laserLineTestBX->value());
        paraList["laserLineTestBY"]=(ui->laserLineTestBY->value());
        paraList["laserLineTestSpacing"]=(ui->laserLineTestSpacing->value());
        paraList["laserLineTestCount"]=(ui->laserLineTestCount->value());
        paraList["comboBox_lineDir"]=(ui->comboBox_lineDir->currentIndex());
        RTC5AGENT.testLines(paraList);
    } break;
    case RTC5TESTTYPE_CIRCLE : {
        paraList["laserCircleTestX"]=(ui->laserCircleTestX->value());
        paraList["laserCircleTestY"]=(ui->laserCircleTestY->value());
        paraList["laserCircleTestR"]=(ui->laserCircleTestR->value());
        RTC5AGENT.testCircle(paraList);
    } break;
    case RTC5TESTTYPE_RECTANGLE : {
        paraList["laserRectangleTestAX"]=(ui->laserRectangleTestAX->value());
        paraList["laserRectangleTestAY"]=(ui->laserRectangleTestAY->value());
        paraList["laserRectangleTestBX"]=(ui->laserRectangleTestBX->value());
        paraList["laserRectangleTestBY"]=(ui->laserRectangleTestBY->value());
        RTC5AGENT.testRectangle(paraList);
    } break;
    case RTC5TESTTYPE_SLICE : {
        paraList["laserPowerByLen2d0"]=(ui->laserPowerByLen2d0->value());
        paraList["laserPowerByLen1d0"]=(ui->laserPowerByLen1d0->value());
        paraList["laserPowerByLen0d5"]=(ui->laserPowerByLen0d5->value());
        paraList["laserPowerByLen0d2"]=(ui->laserPowerByLen0d2->value());
        RTC5AGENT.testSlicelayer(paraList);
    } break;
    default:break;
    }
}

void DialogLaserTest::on_pushButton_stopTest_clicked()
{
    RTC5AGENT.MarkStop();
}

void DialogLaserTest::on_pushButton_saveParas_clicked()
{
    try {
        QObjectList objectList = ui->widget_savePara->children();

        for(auto it : objectList){
            if(it->metaObject()->className()==QString("QSpinBox")){
                SYSTEMCONFIG.setLongValue(PARAMETER,it->objectName().toStdString(), dynamic_cast<QSpinBox*>(it)->value());
            }else if(it->metaObject()->className()==QString("QDoubleSpinBox")){
                SYSTEMCONFIG.setDoubleValue(PARAMETER,it->objectName().toStdString(),dynamic_cast<QDoubleSpinBox*>(it)->value());
            }else if(it->metaObject()->className()==QString("QLineEdit")){
                SYSTEMCONFIG.setValue(PARAMETER,it->objectName().toStdString(),dynamic_cast<QLineEdit*>(it)->text().toStdString());
            }
        }

        SYSTEMCONFIG.saveFile(CONFIGPATH);
    } catch (std::exception & e) {
        HIM_ERROR("DialogLaserTest save parameter to {} error.",e.what());
    }
}

void DialogLaserTest::on_pushButton_resetParas_clicked()
{
    initParas();
}

void DialogLaserTest::on_radioButton_safeCheck_clicked(bool checked)
{
    safeCheck = checked;
    if(checked){
        ui->radioButton_laserEnable->setChecked(false);
        RTC5AGENT.ctlEnableLaser(false);
    }
}

void DialogLaserTest::on_pushButton_openCaliFile_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(
                this, tr("Select a calibration file"), "../data/rtc5/", tr("CT5 Files (*.ct5)"),nullptr,QFileDialog::ReadOnly);
    if(filePath!=NULL){
        ui->laserCalibrationFilePath->setText(filePath);
    }
}

void DialogLaserTest::on_pushButton_applyCaliFile_clicked()
{
    RTC5AGENT.LoadCt5(ui->laserCalibrationFilePath->text().toStdString(),0);
}

void DialogLaserTest::on_radioButton_skyWritingOn_clicked(bool checked)
{
    RTC5AGENT.setSkyWritingOn(checked);
}
